# 读mp3文件并且绘制波形
import pydub 
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示符号

def readMP3(f):
    """读取mp3格式信息"""
    a = pydub.AudioSegment.from_mp3(f)   #  AudioSegment读取mp3文件
    # print(a)
    nchannels = a.channels   # nchannels通道数 = 2
    framerate = a.frame_rate    # framerate采样频率 = 48000
    nframes = int(a.frame_count())    # 采样点数 = 617400
    str_data = a.raw_data    # str_data二进制的, 而get_array_of_samples()返回正常数值
    return nchannels, framerate, nframes

def mp3_to_np(f, normalized=False):
    """MP3 to numpy array"""
    a = pydub.AudioSegment.from_mp3(f)   
    # print(a.get_array_of_samples())
    y = np.array(a.get_array_of_samples())    #  get_array_of_samples()函数将mp3文件读为数组
    #  频道数只有0和1，即左声道和右声道
    if a.channels == 2:    
        y = y.reshape((-1, 2))
    #  即对采样点数进行归一化操作
    if normalized:    
        return np.float32(y) / 2**15
    else:
        return y

def frameTime(f):
    """通过采样点数和取样频率计算出每个取样的时间"""
    nframes = readMP3(f)[2]    # nframes采样点数 = 617400
    framerate = readMP3(f)[1]   # framerate采样频率 = 48000
    time = np.arange(0, nframes) * (1.0 / framerate)
    return np.round(time, 5)

def write_csv(f):
    """生成csv文件"""
    data = mp3_to_np(f, normalized=False)
    print(data)
    dict_data = {'mp3_data1': data[:, 0], 'mp3_data2': data[:, 1]}
    dataframe = pd.DataFrame(dict_data, index=list(frameTime(f)))
    # dataframe = pd.DataFrame.from_dict({'Time(s)': time, 'mp3_data1': data[:, 0], 'mp3_data2': data[:, 1]},
    #                                    orient='index')
    # invert = dataframe.T
    dataframe.to_csv("mp3_to_np.csv", index=True, sep=',')

def pltShow(f):
    """将读取的mp3文件通过采样率绘制波形"""
    data = mp3_to_np(f, normalized=False)
    # frameTime(f)
    plt.figure()
    # 左声道波形
    plt.subplot(2, 1, 1)
    plt.plot(frameTime(f), data[:, 0])  # data第一列
    plt.xlabel("时间/s", fontsize=14)
    plt.ylabel("幅度", fontsize=14)
    plt.title("左声道", fontsize=14)
    plt.grid()  # 标尺

    plt.subplot(2, 1, 2)
    # 右声道波形
    plt.plot(frameTime(f), data[:, 1], c='g')  # data第二列
    plt.xlabel("时间/s", fontsize=14)
    plt.ylabel("幅度", fontsize=14)
    plt.title("右声道", fontsize=14)

    plt.tight_layout()  # 紧密布局
    plt.show()

if __name__ =='__main__':
    mp3_to_np("wokan14s.mp3", normalized=False)
    frameTime("wokan14s.mp3")
    write_csv("wokan14s.mp3")
    pltShow("wokan14s.mp3")
    
